const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const path = require('path');
const cookieParser = require('cookie-parser');
const jwt = require('jsonwebtoken');
const { User } = require('./models/User');
const Message = require('./models/Message');
const { Op } = require('sequelize');
const sequelize = require('./config/database');
const multer = require('multer');
const fs = require('fs');
const authRouter = require('./routes/auth');
const friendsRouter = require('./routes/friends');

// JWT密钥
const JWT_SECRET = 'your-jwt-secret';

const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });

// 配置文件上传
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        const dir = path.join(__dirname, 'uploads');
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, { recursive: true });
        }
        cb(null, dir);
    },
    filename: function (req, file, cb) {
        // 解码文件名
        const decodedFilename = Buffer.from(file.originalname, 'latin1').toString('utf8');
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
        cb(null, uniqueSuffix + '-' + decodedFilename);
    }
});

const upload = multer({
    storage: storage,
    limits: {
        fileSize: 10 * 1024 * 1024 // 限制文件大小为10MB
    }
});

// 连接数据库
sequelize.sync({ alter: true })
    .then(() => {
        console.log('数据库连接成功');
        // 启动服务器
        const PORT = process.env.PORT || 3000;
        server.listen(PORT, () => {
            console.log(`服务器运行在端口 ${PORT}`);
        });
    })
    .catch(err => {
        console.error('数据库连接失败:', err);
        process.exit(1);  // 如果数据库连接失败，终止服务器
    });

// 错误处理中间件
app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).json({ 
        error: '服务器错误',
        message: err.message 
    });
});

// 传递WebSocket服务器实例到路由
authRouter.setWebSocketServer(wss);

// 中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));

// 路由
app.use('/api/auth', authRouter);
app.use('/api/friends', friendsRouter);

// 文件上传路由
app.post('/api/upload', upload.single('file'), (req, res) => {
    try {
        if (!req.file) {
            return res.status(400).json({ msg: '没有文件被上传' });
        }

        // 解码原始文件名
        const decodedFilename = Buffer.from(req.file.originalname, 'latin1').toString('utf8');
        const fileUrl = `/uploads/${req.file.filename}`;
        const fileType = req.file.mimetype.startsWith('image/') ? 'image' : 'file';
        
        res.json({
            url: fileUrl,
            type: fileType,
            filename: decodedFilename
        });
    } catch (err) {
        console.error('文件上传失败:', err);
        res.status(500).json({ msg: '文件上传失败' });
    }
});

// API路由：获取历史消息
app.get('/api/messages/:friendId', async (req, res) => {
    try {
        const token = req.headers['x-auth-token'];
        const decoded = jwt.verify(token, JWT_SECRET);
        const userId = decoded.user.id;
        const friendId = parseInt(req.params.friendId);

        const messages = await Message.findAll({
            where: {
                [Op.or]: [
                    { senderId: userId, receiverId: friendId },
                    { senderId: friendId, receiverId: userId }
                ]
            },
            order: [['createdAt', 'ASC']],
            include: [
                { 
                    model: User, 
                    as: 'sender', 
                    attributes: ['id', 'account', 'avatar']
                },
                { 
                    model: User, 
                    as: 'receiver', 
                    attributes: ['id', 'account', 'avatar']
                }
            ]
        });

        // 获取当前用户和好友的最新信息
        const [currentUser, friend] = await Promise.all([
            User.findByPk(userId, {
                attributes: ['id', 'account', 'avatar']
            }),
            User.findByPk(friendId, {
                attributes: ['id', 'account', 'avatar']
            })
        ]);

        // 更新消息中的用户信息为最新状态
        const updatedMessages = messages.map(msg => {
            const message = msg.toJSON();
            message.sender = message.sender.id === userId ? currentUser : friend;
            message.receiver = message.receiver.id === userId ? currentUser : friend;
            return message;
        });

        res.json(updatedMessages);
    } catch (err) {
        console.error(err);
        res.status(500).json({ msg: '获取消息失败' });
    }
});

// 存储所有连接的客户端
const clients = new Map();

// WebSocket连接处理
wss.on('connection', (ws) => {
    let userId = null;

    ws.on('message', async (message) => {
        try {
            const data = JSON.parse(message);
            
            if (data.type === 'auth') {
                try {
                    const decoded = jwt.verify(data.token, JWT_SECRET);
                    userId = decoded.user.id;
                    ws.userId = userId; // 存储用户ID到WebSocket连接
                    const user = await User.findByPk(userId);
                    
                    if (!user) {
                        ws.send(JSON.stringify({
                            type: 'error',
                            message: '用户不存在'
                        }));
                        return;
                    }

                    clients.set(userId, {
                        ws,
                        user: {
                            id: user.id,
                            account: user.account,
                            avatar: user.avatar
                        }
                    });

                    // 获取所有好友列表
                    const friends = await user.getFriends({
                        through: {
                            where: {
                                status: 'accepted'
                            }
                        },
                        attributes: ['id', 'account', 'avatar']
                    });

                    ws.send(JSON.stringify({
                        type: 'friendList',
                        friends: friends.map(friend => ({
                            id: friend.id,
                            account: friend.account,
                            avatar: friend.avatar,
                            online: clients.has(friend.id)
                        }))
                    }));
                } catch (err) {
                    console.error('WebSocket认证错误:', err);
                    ws.send(JSON.stringify({
                        type: 'error',
                        message: '认证失败'
                    }));
                }
            } else if (data.type === 'message' && userId) {
                const sender = clients.get(userId);
                if (sender && data.to) {
                    // 保存消息到数据库
                    const message = await Message.create({
                        senderId: userId,
                        receiverId: data.to,
                        content: JSON.stringify({
                            type: data.contentType || 'text',
                            content: data.content,
                            filename: data.filename
                        })
                    });

                    const messageData = {
                        type: 'message',
                        id: message.id,
                        from: sender.user,
                        contentType: data.contentType || 'text',
                        content: data.content,
                        filename: data.filename,
                        timestamp: message.createdAt
                    };

                    // 发送给接收者
                    const recipient = clients.get(data.to);
                    if (recipient) {
                        recipient.ws.send(JSON.stringify(messageData));
                    }

                    // 发送给发送者
                    ws.send(JSON.stringify(messageData));
                }
            }
        } catch (err) {
            console.error('WebSocket消息处理错误:', err);
            ws.send(JSON.stringify({
                type: 'error',
                message: '消息处理失败'
            }));
        }
    });

    ws.on('close', () => {
        if (userId) {
            clients.delete(userId);
            broadcastUserStatus(userId, false);
        }
    });

    ws.on('error', (err) => {
        console.error('WebSocket错误:', err);
    });
});

async function broadcastUserStatus(userId, isOnline) {
    try {
        const user = await User.findByPk(userId);
        if (user) {
            const friends = await user.getFriends({
                through: {
                    where: {
                        status: 'accepted'
                    }
                }
            });
            friends.forEach(friend => {
                const friendClient = clients.get(friend.id);
                if (friendClient) {
                    friendClient.ws.send(JSON.stringify({
                        type: 'userStatus',
                        userId: userId,
                        online: isOnline
                    }));
                }
            });
        }
    } catch (err) {
        console.error('广播用户状态失败:', err);
    }
} 